package typedefault

import (
	"codejy/store"
	"codejy/structdef"
	"fmt"

	"strconv"
	"strings"
	"time"
)

// key 实例地址,value 值

type Time struct {
	Addr        string
	ThreadStore *structdef.ThreadStore
}

func (f *Time) CreateTypeDefault(addr string, threadStore *structdef.ThreadStore, parameter ...string) {
	fUtil := &Time{
		Addr:        addr,
		ThreadStore: threadStore,
	}
	store.AddTypeDefaultInstanceStore(threadStore, f.GetTypeName(), addr, fUtil)
}
func (f *Time) GetData() interface{} {
	return nil
}

func (a *Time) ToStr() string {
	return ""
}
func (a *Time) ParameterProcessing(parameter []string) []string {
	//排除前后""
	for i := range parameter {
		s := parameter[i]
		if strings.HasPrefix(s, "\"") && strings.HasSuffix(s, "\"") {
			s = s[1 : len(s)-1]
			parameter[i] = s
		}
	}
	return parameter
}

// 获取当前时间戳秒
func (a *Time) Now() string {
	unix := time.Now().Unix()
	return strconv.FormatInt(unix, 10)
}

// 获取当前时间戳毫秒
func (a *Time) NowMilli() string {
	unix := time.Now().UnixMilli()
	return strconv.FormatInt(unix, 10)
}

// 获取当前时间戳微秒
func (a *Time) NowMicro() string {
	unix := time.Now().UnixMicro()
	return strconv.FormatInt(unix, 10)
}

// 获取时间戳的年
func (a *Time) Year(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp = timestamp[0:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			return strconv.Itoa(t.Year())
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的年失败", timestamp)
	panic(fmt1)
}

// 获取时间戳的月
func (a *Time) Month(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp = timestamp[0:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			return strconv.Itoa(int(t.Month()))
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的月失败", timestamp)
	panic(fmt1)
}

// 获取时间戳的周
func (a *Time) Week(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp = timestamp[0:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			itoa := strconv.Itoa(int(t.Weekday()))
			// 周日是0
			if itoa == "0" {
				return "7"
			}
			return itoa
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的周失败", timestamp)
	panic(fmt1)
}

// 获取时间戳的日
func (a *Time) Day(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp = timestamp[0:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			return strconv.Itoa(t.Day())
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的日失败", timestamp)
	panic(fmt1)
}

// 获取时间戳的时
func (a *Time) Hour(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp = timestamp[0:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			return strconv.Itoa(t.Hour())
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的时失败", timestamp)
	panic(fmt1)
}

// 获取时间戳的分
func (a *Time) Minute(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp = timestamp[0:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			return strconv.Itoa(t.Minute())
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的分失败", timestamp)
	panic(fmt1)
}

// 获取时间戳的秒
func (a *Time) Second(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 10 {
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.Unix(i, 0)
			return strconv.Itoa(t.Second())
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的秒失败,不能为空并且长度必须大于等于10", timestamp)
	panic(fmt1)
}

// 获取时间戳的毫秒
func (a *Time) Milli(timestamp string) string {
	if timestamp != "" && len(timestamp) >= 13 {
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.UnixMilli(i)
			return strconv.Itoa(t.Nanosecond() / 1000000)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的毫秒失败,不能为空并且长度必须大于等于13位", timestamp)
	panic(fmt1)
}

// 获取时间戳的微秒
func (a *Time) Micro(timestamp string) string {
	if timestamp != "" && len(timestamp) == 16 {
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			t := time.UnixMicro(i)
			return strconv.Itoa(t.Nanosecond() / 1000)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s时间戳的微秒失败,不能为空并且长度必须是16位", timestamp)
	panic(fmt1)
}

// 获取n分钟有多少秒
func (a *Time) Minutes(n string) string {
	if n != "" {
		i, err := strconv.Atoi(n)
		if err == nil {
			return strconv.Itoa(i * 60)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s分钟有多少秒失败", n)
	panic(fmt1)
}

// 获取n小时有多少秒
func (a *Time) Hours(n string) string {
	if n != "" {
		i, err := strconv.Atoi(n)
		if err == nil {
			return strconv.Itoa(i * 60 * 60)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s小时有多少秒失败", n)
	panic(fmt1)
}

// 获取n天有多少秒
func (a *Time) Days(n string) string {
	if n != "" {
		i, err := strconv.Atoi(n)
		if err == nil {
			return strconv.Itoa(i * 60 * 60 * 24)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s天有多少秒失败", n)
	panic(fmt1)
}

// 获取n周有多少秒
func (a *Time) Weeks(n string) string {
	if n != "" {
		i, err := strconv.Atoi(n)
		if err == nil {
			return strconv.Itoa(i * 60 * 60 * 24 * 7)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s周有多少秒失败", n)
	panic(fmt1)
}

// 获取n月有多少秒
func (a *Time) Months(n string) string {
	if n != "" {
		i, err := strconv.Atoi(n)
		if err == nil {
			return strconv.Itoa(i * 60 * 60 * 24 * 30)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s月有多少秒失败", n)
	panic(fmt1)
}

// 获取n年有多少秒
func (a *Time) Years(n string) string {
	if n != "" {
		i, err := strconv.Atoi(n)
		if err == nil {
			return strconv.Itoa(i * 60 * 60 * 24 * 365)
		}
	}
	var fmt1 = fmt.Sprintf("获取%s年有多少秒失败", n)
	panic(fmt1)
}

// 时间戳加上n秒
func (a *Time) Add(timestamp string, n string) string {
	if timestamp != "" && n != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp1 := timestamp[10:]
		timestamp = timestamp[:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			j, err := strconv.Atoi(n)
			if err == nil {
				formatInt := strconv.FormatInt(i+int64(j), 10)
				return formatInt + timestamp1
			}
		}
	}
	var fmt1 = fmt.Sprintf("%s时间戳加上%s秒失败,时间戳和秒不能为空并且必须大于等于10位", timestamp, n)
	panic(fmt1)
}

// 时间戳减去n秒
func (a *Time) Sub(timestamp string, n string) string {
	if timestamp != "" && n != "" && len(timestamp) >= 10 {
		//截取前10位
		timestamp1 := timestamp[10:]
		timestamp = timestamp[:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			j, err := strconv.Atoi(n)
			if err == nil {
				formatInt := strconv.FormatInt(i-int64(j), 10)
				return formatInt + timestamp1
			}
		}
	}
	var fmt1 = fmt.Sprintf("%s时间戳减去%s秒失败,时间戳和秒不能为空并且必须大于等于10位", timestamp, n)
	panic(fmt1)
}

// 时间戳转换为字符串
func (a *Time) Format(timestamp string, format string) string {
	if timestamp != "" && format != "" && len(timestamp) >= 10 {
		timestamp = timestamp[:10]
		i, err := strconv.ParseInt(timestamp, 10, 64)
		if err == nil {
			//将yyyy-MM-dd HH:mm:ss.SSS转换为go的时间格式2006-01-02 15:04:05.000
			format = strings.Replace(format, "yyyy", "2006", -1)
			format = strings.Replace(format, "MM", "01", -1)
			format = strings.Replace(format, "dd", "02", -1)
			format = strings.Replace(format, "HH", "15", -1)
			format = strings.Replace(format, "mm", "04", -1)
			format = strings.Replace(format, "ss", "05", -1)
			return time.Unix(i, 0).Format(format)
		}
	}
	var fmt1 = fmt.Sprintf("时间戳转换失败,timestamp:%s,format:%s", timestamp, format)
	panic(fmt1)

}

// 将字符串转换为时间戳
func (a *Time) Parse(str string, format string) string {
	if str != "" {
		//将yyyy-MM-dd HH:mm:ss.SSS转换为go的时间格式2006-01-02 15:04:05.000
		format = strings.Replace(format, "yyyy", "2006", -1)
		format = strings.Replace(format, "MM", "01", -1)
		format = strings.Replace(format, "dd", "02", -1)
		format = strings.Replace(format, "HH", "15", -1)
		format = strings.Replace(format, "mm", "04", -1)
		format = strings.Replace(format, "ss", "05", -1)
		format = strings.Replace(format, "SSS", "000", -1)
		parse, err := time.ParseInLocation(format, str, time.Local)
		if err == nil {
			return strconv.FormatInt(parse.Unix(), 10)
		}
	}
	panic(str + "时间转换失败")
}

// 时间比较,如果time1大于time2返回1，如果time1小于time2返回-1，如果time1等于time2返回0
func (a *Time) CompareTime(time1 string, time2 string) string {
	if time1 != "" && time2 != "" && len(time1) >= 10 && len(time2) >= 10 {
		time1 = time1[:10]
		time2 = time2[:10]
		i, err := strconv.ParseInt(time1, 10, 64)
		if err == nil {
			j, err := strconv.ParseInt(time2, 10, 64)
			if err == nil {
				if i > j {
					return "1"
				} else if i < j {
					return "-1"
				} else {
					return "0"
				}
			}
		}

	}
	var fmt1 = fmt.Sprintf("时间比较失败,time1:%s,time2:%s ,时间戳不能是空并且长度大于等于10", time1, time2)
	panic(fmt1)
}

func (f *Time) GetDef() string {
	return `
		@CodeManual(def="Time.xxx",des="时间操作")
		type share Time{
			def init{
				core&CreateTypeDefault()
			}
			@CodeManual(def="Time.now()",des="获取当前时间戳(单位秒,10位)")
			def now{
			  to core&Now()
			}
			@CodeManual(def="Time.nowMilli()",des="获取当前时间戳(单位毫秒,13位)")
			def nowMilli{
			  to core&NowMilli()
			}
			@CodeManual(def="Time.nowMicro()",des="获取当前时间戳(单位微秒,16位)")
			def nowMicro{
			  to core&NowMicro()
			}
			@CodeManual(def="Time.Year(?)",des="传入时间戳,获取时间戳的年份,返回数字")
			def year{
			  to core&Year($1)
			}
			@CodeManual(def="Time.Month(?)",des="传入时间戳,获取时间戳的月份,返回数字")
			def month{
			  to core&Month($1)
			}
			@CodeManual(def="Time.Day(?)",des="传入时间戳,获取时间戳的天,返回数字")
			def week{
			  to core&Week($1)
			}
			@CodeManual(def="Time.Day(?)",des="传入时间戳,获取时间戳的天,返回数字")
			def day{
			  to core&Day($1)
			}

			@CodeManual(def="Time.Hour(?)",des="传入时间戳,获取时间戳的小时,返回数字")
			def hour{
			  to core&Hour($1)	
			}

			@CodeManual(def="Time.Minute(?)",des="传入时间戳,获取时间戳的分钟,返回数字")
			def minute{
			  to core&Minute($1)
			}

			@CodeManual(def="Time.Second(?)",des="传入时间戳,获取时间戳的秒,返回数字")
			def second{
			  to core&Second($1)
			}

			@CodeManual(def="Time.Milli(?)",des="传入时间戳,获取时间戳的毫秒,返回数字")
			def milli{
			  to core&Milli($1)
			}

			@CodeManual(def="Time.Micro(?)",des="传入时间戳,获取时间戳的微秒,返回数字")
			def micro{
			  to core&Micro($1)
			}
			
			@CodeManual(def="Time.Nano(?)",des="传入时间戳,获取时间戳的纳秒,返回数字")
			def minutes{
			  to core&Minutes($1)
			}
			
			@CodeManual(def="Time.Hours(?)",des="获取n小时有多少秒,返回数字")
			def hours{
			  to core&Hours($1)
			}
			@CodeManual(def="Time.Days(?)",des="获取n天有多少秒,返回数字")
			def days{
			  to core&Days($1)
			}

			@CodeManual(def="Time.Weeks(?)",des="获取n周有多少秒,返回数字")
			def weeks{
			  to core&Weeks($1)
			}
			@CodeManual(def="Time.Months(?)",des="获取n月有多少秒,返回数字")
			def months{
			  to core&Months($1)
			}

			@CodeManual(def="Time.Years(?)",des="获取n年有多少秒,返回数字")
			def years{
			  to core&Years($1)
			}

			@CodeManual(def="Time.Add(?,?)",des="传入时间戳和秒数,返回相加后的时间戳")
			def add{
			  to core&Add($1,$2)
			}
			@CodeManual(def="Time.Sub(?,?)",des="传入时间戳和秒数,返回相减后的时间戳")
			def sub{
			  to core&Sub($1,$2)
			}
			@CodeManual(def="Time.Format(?,?)",des="传入时间戳和格式,返回格式化后的时间,只支持Y M D H m s S")
			def format{
			  to core&Format($1,$2)
			}
			@CodeManual(def="Time.Parse(?,?)",des="传入时间和格式,返回时间戳,只支持Y M D H m s S")
			def parse{
			  to core&Parse($1,$2)
			}
			@CodeManual(def="Time.Compare(?,?)",des="传入时间戳和时间戳,返回: 1表示第一个时间大,0表示相等,-1表示第1个时间小")
			def compare{
			  to core&CompareTime($1,$2)
			}
		
		}
	`
}

func init() {
	RegisterTypeDefault(&Time{})
}
func (f *Time) GetTypeName() string {
	return "Time"
}
